package com.hxkj.service.impl;

import com.hxkj.dao.AuthFunctionDao;
import com.hxkj.dao.FunctionLibraryDao;
import com.hxkj.domain.enums.FunctionLibraryExceptionEnum;
import com.hxkj.domain.po.AuthFunction;
import com.hxkj.domain.po.FunctionLibrary;
import com.hxkj.domain.po.FunctionLibraryTree;
import com.hxkj.service.FunctionLibraryService;
import com.platform.common.domain.result.ResultMessageStruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName FunctionLibraryServiceImpl
 * @Description TODO
 * @Author Mr.zheng
 * @Date 2018/6/27 11:25
 * @Version 1.0
 */
@Service
@Slf4j
public class FunctionLibraryServiceImpl implements FunctionLibraryService {

    @Autowired
    private FunctionLibraryDao functionLibraryDao;
    @Autowired
    private AuthFunctionDao authFunctionDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct saveFunctionLibrary(FunctionLibrary functionLibrary) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            int i = functionLibraryDao.saveFunctionLibrary(functionLibrary);

            resultMessageStruct.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(FunctionLibraryExceptionEnum.FUNCTION_SAVE_ERROR.getCode());
            resultMessageStruct.setMessage(FunctionLibraryExceptionEnum.FUNCTION_SAVE_ERROR.getMsg());
        }
        return resultMessageStruct;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct modifyFunctionLibrary(FunctionLibrary functionLibrary) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            int i = functionLibraryDao.modifyFunctionLibrary(functionLibrary);
            if (i == 1) {
                //修改子节点状态
                updateFunctionLibraryStatus(functionLibrary.getId(), functionLibrary.getFunctionStatus());

                resultMessageStruct.setCode(200);
            } else {
                resultMessageStruct.setCode(FunctionLibraryExceptionEnum.FUNCTION_UPDATE_ERROR.getCode());
                resultMessageStruct.setMessage(FunctionLibraryExceptionEnum.FUNCTION_UPDATE_ERROR.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(FunctionLibraryExceptionEnum.FUNCTION_UPDATE_ERROR.getCode());
            resultMessageStruct.setMessage(FunctionLibraryExceptionEnum.FUNCTION_UPDATE_ERROR.getMsg());
        }
        return resultMessageStruct;
    }

    private void updateFunctionLibraryStatus(Long id, Byte functionStatus) {
        FunctionLibrary functionLibrary = new FunctionLibrary();
        functionLibrary.setParentFunctionId(id);
        //Mr.zheng: 根据id来查询父节点是否有他
        List<FunctionLibrary> list = functionLibraryDao.getFunctionLibraryList(functionLibrary);
        if (null == list || list.size() < 1) {
            return;
        }
        //Mr.zheng:修改所有子节点
        functionLibrary = new FunctionLibrary();
        functionLibrary.setParentFunctionId(id);
        functionLibrary.setFunctionStatus(functionStatus);
        functionLibraryDao.modifyFunctionLibraryStatus(functionLibrary);
        //Mr.zheng:递归修改子节点
        for (FunctionLibrary flib : list) {
//            if(flib.getFunctionType() == 1){
            updateFunctionLibraryStatus(flib.getId(), functionStatus);
//            }
        }
    }

    @Override
    public List<FunctionLibraryTree> getFunctionLibraryListTree(FunctionLibrary functionLibrary) throws Exception {
        List<FunctionLibraryTree> functionLibraryTreeList = new ArrayList<FunctionLibraryTree>();
        try {
            functionLibraryTreeList = initTree(-1, functionLibrary);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return functionLibraryTreeList;
    }

    @Override
    public List<FunctionLibraryTree> getShowFunctionLibraryListTree(FunctionLibrary functionLibrary) throws Exception {
        List<FunctionLibraryTree> functionLibraryTreeList = new ArrayList<FunctionLibraryTree>();
        try {
            functionLibraryTreeList = initShowTree(-1, functionLibrary);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return functionLibraryTreeList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct removeFunctionLibrary(FunctionLibrary functionLibrary) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            //Mr.zheng:查看是否有子节点ID
            int count = functionLibraryDao.countFunctionLibrarieByParentId(functionLibrary.getId());
            if (count != 0) {
                resultMessageStruct.setCode(FunctionLibraryExceptionEnum.FUNCTION_IS_PARENT.getCode());
                return resultMessageStruct;
            }
            functionLibraryDao.removeFunctionLibrary(functionLibrary);
            resultMessageStruct.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(FunctionLibraryExceptionEnum.FUNCTION_DELETE_ERROR.getCode());
            resultMessageStruct.setMessage(FunctionLibraryExceptionEnum.FUNCTION_DELETE_ERROR.getMsg());
        }
        return resultMessageStruct;
    }

    @Override
    public void functionToSite(FunctionLibrary functionLibrary) throws Exception {
        // 清除已分配的功能库功能
        authFunctionDao.removeFunction(functionLibrary.getSiteId());

        // 获取选择的功能库功能
        functionLibraryDao.getFunctionLibraryList(functionLibrary).parallelStream().map(item -> {
            // 重新添加功能
            AuthFunction authFunction = new AuthFunction();
            BeanUtils.copyProperties(item, authFunction);
            authFunction.setFunctionId(item.getId());
            authFunction.setFunctionLibraryId(item.getId());
            authFunction.setSiteId(functionLibrary.getSiteId());
            authFunctionDao.save(authFunction);
            return authFunction;
        }).collect(Collectors.toList());

    }


    @Override
    public List<FunctionLibraryTree> getFunctionLibraryListTreeByKeyword(FunctionLibrary functionLibrary) throws Exception {
        List<FunctionLibraryTree> functionLibraryTreeList = new ArrayList<>();
        try {
            List<FunctionLibrary> functionLibraryList = functionLibraryDao.getFunctionLibraryList(functionLibrary);
            for (FunctionLibrary funl : functionLibraryList) {
                FunctionLibraryTree functionLibraryTree = new FunctionLibraryTree();
                int count = 0;//Mr.zheng:定义控制器，判断是否添加了重复的父节点
                if (funl.getParentFunctionId() != -1) {
                    //Mr.zheng:递归调用获取顶级父节点ID
                    FunctionLibrary fu = getFunctionLibraryByParentId(funl.getParentFunctionId());
                    //Mr.zheng:根据顶级父节点ID封装
                    functionLibraryTree = addParentFunctionLibrary(fu);
                    //Mr.zheng:查看是否有相同的顶级父节点，如果有就跳出循环
                    for (FunctionLibraryTree functionLibraryTree1 : functionLibraryTreeList) {
                        if (functionLibraryTree.getId() == functionLibraryTree1.getId()) {
                            count++;
                            break;
                        }
                    }
                    if (count == 0) {
                        functionLibraryTreeList.add(functionLibraryTree);
                    }
                } else {
                    //Mr.zheng:根据顶级父节点ID封装
                    functionLibraryTree = addParentFunctionLibrary(funl);
                    //Mr.zheng:查看是否有相同的顶级父节点，如果有就跳出循环
                    for (FunctionLibraryTree functionLibraryTree1 : functionLibraryTreeList) {
                        if (functionLibraryTree.getId() == functionLibraryTree1.getId()) {
                            count++;
                            break;
                        }
                    }
                    if (count == 0) {
                        functionLibraryTreeList.add(functionLibraryTree);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        return functionLibraryTreeList;
    }

    //Mr.zheng:递归调用获取顶级父节点
    private FunctionLibrary getFunctionLibraryByParentId(Long parentFunctionId) {
        FunctionLibrary functionLibrary = functionLibraryDao.getFunctionLibraryById(parentFunctionId);
        if (functionLibrary.getParentFunctionId() != -1) {
            getFunctionLibraryByParentId(functionLibrary.getParentFunctionId());
        }
        return functionLibrary;
    }

    //Mr.zheng:递归插入数据，修改parentId
    private int initTreeInsert(long id, long parentFunctionId, List<FunctionLibrary> functionLibraryList, long siteId) throws Exception {
        for (FunctionLibrary functionLibrary : functionLibraryList) {
            if (functionLibrary.getParentFunctionId() == id) {
                AuthFunction authFunction = new AuthFunction();
                //Mr.zheng:插入数据获取插入数据的ID
                authFunction.setParentFunctionId(parentFunctionId);
                authFunction.setFunctionName(functionLibrary.getFunctionName() == null ? "" : functionLibrary.getFunctionName());
                authFunction.setFunctionUri(functionLibrary.getFunctionUri() == null ? "" : functionLibrary.getFunctionUri());
                authFunction.setFunctionCode(functionLibrary.getFunctionCode() == null ? "" : functionLibrary.getFunctionCode());
                authFunction.setFunctionStatus(functionLibrary.getFunctionStatus() == null ? Byte.parseByte("") : functionLibrary.getFunctionStatus());
                authFunction.setFunctionType(functionLibrary.getFunctionType() == null ? Byte.valueOf("") : functionLibrary.getFunctionType());
                authFunction.setFunctionIcon(functionLibrary.getFunctionIcon() == null ? "" : functionLibrary.getFunctionIcon());
                authFunction.setSiteId(siteId);
                //TODO:没有获取到插入数据ID
                functionLibraryDao.saveFunction(authFunction);

                initTreeInsert(functionLibrary.getId(), authFunction.getFunctionId(), functionLibraryList, siteId);
            } else {
                continue;
            }
        }
        return 0;
    }


    private List<FunctionLibraryTree> initTree(long id, FunctionLibrary aufc) throws Exception {
        List<FunctionLibraryTree> functionLibraryTrees = new ArrayList<FunctionLibraryTree>();
        FunctionLibrary functionLibrary = new FunctionLibrary();
        functionLibrary.setParentFunctionId(id);
        functionLibrary.setFunctionName(aufc == null ? "" : aufc.getFunctionName().trim());
        List<FunctionLibrary> functionLibraries = functionLibraryDao.getFunctionLibrarieList(functionLibrary);
        if (functionLibraries != null && functionLibraries.size() != 0) {
            FunctionLibraryTree functionLibraryTree;
            for (FunctionLibrary auf : functionLibraries) {
                functionLibraryTree = new FunctionLibraryTree();
                functionLibraryTree.setFunctionName(auf.getFunctionName() == null ? "" : auf.getFunctionName());
                functionLibraryTree.setFunctionUri(auf.getFunctionUri() == null ? "" : auf.getFunctionUri());
                functionLibraryTree.setId(auf.getId());
                functionLibraryTree.setParentFunctionId(auf.getParentFunctionId());
                functionLibraryTree.setFunctionCode(auf.getFunctionCode() == null ? "" : auf.getFunctionCode());
                functionLibraryTree.setFunctionStatus(auf.getFunctionStatus() == null ? Byte.parseByte("") : auf.getFunctionStatus());
                functionLibraryTree.setFunctionType(auf.getFunctionType() == null ? Byte.valueOf("") : auf.getFunctionType());
                functionLibraryTree.setFunctionIcon(auf.getFunctionIcon() == null ? "" : auf.getFunctionIcon());
                functionLibraryTree.setCreateTime(auf.getCreateTime());
                functionLibraryTree.setUpdateTime(auf.getUpdateTime());
                //避免跟搜索混淆
                auf.setFunctionName("");
                functionLibraryTree.setChildren(initTree(auf.getId(), auf));
                functionLibraryTrees.add(functionLibraryTree);
            }
        }
        return functionLibraryTrees;
    }


    private FunctionLibraryTree addParentFunctionLibrary(FunctionLibrary auf) throws Exception {
        FunctionLibraryTree functionLibraryTree = new FunctionLibraryTree();
        functionLibraryTree.setFunctionName(auf.getFunctionName() == null ? "" : auf.getFunctionName());
        functionLibraryTree.setFunctionUri(auf.getFunctionUri() == null ? "" : auf.getFunctionUri());
        functionLibraryTree.setId(auf.getId());
        functionLibraryTree.setParentFunctionId(auf.getParentFunctionId());
        functionLibraryTree.setFunctionCode(auf.getFunctionCode() == null ? "" : auf.getFunctionCode());
        functionLibraryTree.setFunctionStatus(auf.getFunctionStatus() == null ? Byte.parseByte("") : auf.getFunctionStatus());
        functionLibraryTree.setFunctionType(auf.getFunctionType() == null ? Byte.valueOf("") : auf.getFunctionType());
        functionLibraryTree.setFunctionIcon(auf.getFunctionIcon() == null ? "" : auf.getFunctionIcon());
        functionLibraryTree.setCreateTime(auf.getCreateTime());
        functionLibraryTree.setUpdateTime(auf.getUpdateTime());
        //避免跟搜索混淆
        auf.setFunctionName("");
        functionLibraryTree.setChildren(initTree(auf.getId(), auf));
        return functionLibraryTree;
    }

    private List<FunctionLibraryTree> initShowTree(long id, FunctionLibrary aufc) throws Exception {
        List<FunctionLibraryTree> functionLibraryTrees = new ArrayList<FunctionLibraryTree>();
        FunctionLibrary functionLibrary = new FunctionLibrary();
        functionLibrary.setParentFunctionId(id);
        List<FunctionLibrary> functionLibraries = functionLibraryDao.getShowFunctionLibrarieList(functionLibrary);
        if (functionLibraries != null && functionLibraries.size() != 0) {
            FunctionLibraryTree functionLibraryTree;
            for (FunctionLibrary auf : functionLibraries) {
                functionLibraryTree = new FunctionLibraryTree();
                functionLibraryTree.setFunctionName(auf.getFunctionName() == null ? "" : auf.getFunctionName());
                functionLibraryTree.setFunctionUri(auf.getFunctionUri() == null ? "" : auf.getFunctionUri());
                functionLibraryTree.setId(auf.getId());
                functionLibraryTree.setParentFunctionId(auf.getParentFunctionId());
                functionLibraryTree.setFunctionCode(auf.getFunctionCode() == null ? "" : auf.getFunctionCode());
                functionLibraryTree.setFunctionStatus(auf.getFunctionStatus() == null ? Byte.parseByte("") : auf.getFunctionStatus());
                functionLibraryTree.setFunctionType(auf.getFunctionType() == null ? Byte.valueOf("") : auf.getFunctionType());
                functionLibraryTree.setFunctionIcon(auf.getFunctionIcon() == null ? "" : auf.getFunctionIcon());
                functionLibraryTree.setCreateTime(auf.getCreateTime());
                functionLibraryTree.setUpdateTime(auf.getUpdateTime());
                //避免跟搜索混淆
                auf.setFunctionName("");
                functionLibraryTree.setChildren(initShowTree(auf.getId(), auf));
                functionLibraryTrees.add(functionLibraryTree);
            }
        }
        return functionLibraryTrees;
    }

//    private void updateFunctionLibraryStatus(Long functionId, Byte functionStatus){
//        FunctionLibrary ath = new FunctionLibrary();
//        ath.setParentFunctionId(functionId);
//        // 根据id来查询父节点是否有他
//        List<FunctionLibrary> list = functionLibraryDao.getFunctionLibraryList(ath);
//        if(null == list || list.size() < 1){
//            return;
//        }
//        //修改所有子节点
//        ath = new FunctionLibrary();
//        ath.setParentFunctionId(functionId);
//        ath.setFunctionStatus(functionStatus);
//        functionLibraryDao.modifyFunctionStatus(ath);
//        //递归修改子节点
//        for (FunctionLibrary functionLibrary: list){
//            if(functionLibrary.getFunctionType() == 1){
//                updateFunctionLibraryStatus(functionLibrary.getId(), functionStatus);
//            }
//        }
//    }
}
